import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:intl/intl.dart';

import 'package:date_format/date_format.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:pax_info_app/db/provider/clock/clock_db_provider.dart';
import 'package:pax_info_app/model/clock_user_info.dart';
import 'package:pax_info_app/model/sys_info.dart';
import 'package:pax_info_app/provider/view_state_model.dart';
import 'package:pax_info_app/repository/app_repository.dart';
import 'package:pax_info_app/ui/pages/clock/clock_list_page.dart';
import 'package:pax_info_app/utils/common_utils.dart';
import 'package:rflutter_alert/rflutter_alert.dart';

class ClockModel extends ViewStateModel {

  final int userNo;
  final String fDate;
  ClockModel(this.userNo, this.fDate);

  late ClockUserInfo _clockUserInfo;
  ClockUserInfo get clockUserInfo => _clockUserInfo;

  Timer? _timer;
  late String _currentDateTime = '';
  String get currentDateTime => _currentDateTime;

  late String _currentTime = '';
  String get currentTime => _currentTime;

  late String _weekDay = '';
  String get weekDay => _weekDay;

  ClockDbProvider clockDbProvider = new ClockDbProvider();

  void _startTimer() {
    const period = const Duration(seconds: 1);
    _timer?.cancel();
    _timer = Timer.periodic(period, (timer) {
      _currentDateTime = formatDate(DateTime.now(), [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn, ':', ss]);
      _currentTime = formatDate(DateTime.now(), [HH, ':', nn, ':', ss]);
      notifyListeners();
    });
  }


  initData() async {
    setBusy();
    try {
      var res = await AppRepository.getUserInfo(userNo, fDate);
      print('=== getUserInfo: ${res.data}');
      _startTimer();
      if (res.valid()) {
        _clockUserInfo = ClockUserInfo.fromJson(res.data);
        SysInfo.instance.clockUserInfoJson = jsonEncode(res.data);
        await SysInfo.instance.save();
        _weekDay = DateFormat('EEEE',"zh_CN").format(DateTime.now());

        List<Map> _periodList = await getClockDateList();
        await getClockList(_periodList[0]['PeriodValue']??fDate);
        await getClockList(_periodList[1]['PeriodValue']??fDate);
        await getClockList(_periodList[2]['PeriodValue']??fDate);
        // await getClockList(_periodList[3]['PeriodValue']??fDate);
        // await getClockList(_periodList[4]['PeriodValue']??fDate);
        // await getClockList(_periodList[5]['PeriodValue']??fDate);
        // print('>>>>> getClockDateList _periodList: $_periodList');
        // await Future.forEach(_periodList, (Map element) async {
        //   print('>>>>>>> _periodList item: $element');
        //   await getClockList(element['PeriodValue']??fDate);
        // });

        setIdle();
        return true;
      } else {
        _clockUserInfo = new ClockUserInfo();
        setEmpty();
        return false;
      }
    } catch (e, s) {
      if (SysInfo.instance.clockUserInfoJson != null &&
          SysInfo.instance.clockUserInfoJson != '') {
        _clockUserInfo = ClockUserInfo.fromJson(
          jsonDecode(SysInfo.instance.clockUserInfoJson??'')
        );
      }
      setError(e,s);
      return false;
    }
  }

  pickImage(BuildContext context, File file) async {
    // File _image;
    // final picker = ImagePicker();
    // final pickedFile = await picker.getImage(source: ImageSource.camera);
    Uint8List? pngBytes = await FlutterImageCompress.compressWithFile(
      file.absolute.path,
      minWidth: 900,
      minHeight: 600,
      quality: 80,
    );
    // Uint8List pngBytes = await file.readAsBytes();
    late String imgBase64;
    if (pngBytes != null) {
      imgBase64 = base64.encode(pngBytes);
    }

    matchPerson(context, imgBase64: imgBase64);
  }

  Future matchPerson(BuildContext context, { String? userName, String? imgBase64 }) async {
    EasyLoading.show();
    var res = await AppRepository.matchPerson(
        userNo,
        userName: userName,
        imgBase64: imgBase64);
    EasyLoading.dismiss();
    if (!res.valid()) {
      // res.showErr();
      Alert(
        context: context,
        type: AlertType.error,
        title: "打卡失败",
        desc: res.message,
        buttons: [
          DialogButton(
            child: Text(
              "确定",
              style: TextStyle(color: Colors.white, fontSize: 20),
            ),
            onPressed: () {
              Navigator.pop(context);
            },
            color: Color.fromRGBO(143, 148, 251, 1),
            radius: BorderRadius.circular(0.0),
          ),
        ],
      ).show();
      return;
    }
    // CommonUtils.toast(res.message);

    Alert(
      context: context,
      type: AlertType.success,
      title: "打卡成功",
      desc: res.message,
      buttons: [
        DialogButton(
          child: Text(
            "确定",
            style: TextStyle(color: Colors.white, fontSize: 20),
          ),
          onPressed: () {

            Navigator.pop(context);
            initData();
            // Navigator.push(
            //     context, MaterialPageRoute(builder: (context) => ClockListPage(fDate))).then((v) {
            //   initData();
            // });
          },
          color: Color.fromRGBO(143, 148, 251, 1),
          radius: BorderRadius.circular(0.0),
        ),
      ],
    ).show();
  }



  Future<List<Map>> getClockDateList() async {
    try {
      var res = await AppRepository.getClockDateList();
      if (!res.valid()) {
        return [{'PeriodValue': fDate}];
      }
      List<Map> _list = [];
      res.data.forEach((ele) {
        _list.add(Map.from(ele));
        // clockDbProvider.insert(Map.from(ele));
      });
      return _list;
    } catch (e, s) {
      print(e);
      return [{'PeriodValue': fDate}];
    }
  }

  getClockList(String date) async {
    try {
      var res = await AppRepository.getClockList(userNo, date);
      print('=== getClockList: ${res.valid()}');
      if (res.valid()) {
        List<Map> _list = [];
        res.data['ClockList'].forEach((ele) {
          _list.add(Map.from(ele));
          // clockDbProvider.insert(Map.from(ele));
        });
        clockDbProvider.batchInsert(_list);
        return true;
      } else {
        return false;
      }
    } catch (e, s) {
      print(e);
      return false;
    }
  }

}